;; core/integer.scm - (c) rohan drape, 2004-2005

;; Exact integer constructors and predicate.

(define (floorE n) (inexact->exact (floor n)))
(define (ceilingE n) (inexact->exact (ceiling n)))
(define (truncateE n) (inexact->exact (truncate n)))
(define (roundE n) (inexact->exact (round n)))
(define (exactI? x) (and (integer? x) (exact? x)))

;; As in SuperCollider.  Return an integer n in b <= n <= c.

(define (integer-wrap n b c) (+ (modulo (- n b) (- c b -1)) b))

;; Increment/decrement.

(define (++ n) (+ n 1))
(define (-- n) (- n 1))

;; Syntax increment/decrement.

(define-syntax ++! (syntax-rules () ((_ n) (set! n (+ n 1)))))
(define-syntax --! (syntax-rules () ((_ n) (set! n (- n 1)))))

;; Variant that returns 0 instead an error on divide by zero.

(define (/* a b) (if (zero? b) 0 (/ a b)))

;; Returns the next integer greater than or equal to `n' that is a
;; power of two.

(define (next-power-of-two n)
  (let loop ((i 1) (j 2))
    (cond ((>= j n) j)
	  (else (loop (+ i 1) (arithmetic-shift 1 (+ i 1)))))))

;; Returns '#t' iff `n' is a power of two.

(define (power-of-two? n) (= n (next-power-of-two n)))

;; Returns the lowest <integer> multiple of `n' that is greater than
;; `i'.

(define (multiple-of? i n)     (= (remainder i n) 0))
(define (next-multiple-of i n) (* (+ (quotient i n) 1) n))

;; Variant of for-each.

(define (integer-iterate/index n p)
  (do ((i 0 (+ i 1)))
      ((= i n))
    (p i)))

(define (integer-iterate n p)
  (if (thunk? p)
      (do ((i 0 (+ i 1)))
	  ((= i n))
	(p))
      (integer-iterate/index n p)))
